const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');
const { Server } = require('socket.io');
const { PrismaClient } = require('@prisma/client');

const dev = process.env.NODE_ENV !== 'production';
const hostname = 'localhost';
const port = parseInt(process.env.PORT || '3000', 10);

// 创建Next.js应用
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();

// 创建Prisma客户端
const prisma = new PrismaClient();

// 价格服务类（简化版）
class PriceService {
  constructor() {
    this.timeout = 15000;
    this.maxRetries = 2;
  }

  async getTokenPrice(contractAddress, chain) {
    console.log(`正在获取价格数据: ${contractAddress} (${chain.toUpperCase()})`);
    
    const axios = require('axios');
    const chainMap = {
      'solana': 'solana',
      'bsc': 'bsc', 
      'base': 'base'
    };

    for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
      try {
        console.log(`DexScreener尝试 ${attempt}/${this.maxRetries}: ${contractAddress}`);
        
        const response = await axios.get(
          `https://api.dexscreener.com/latest/dex/tokens/${contractAddress}`,
          {
            timeout: this.timeout,
            headers: {
              'User-Agent': 'MemeBot/1.0',
              'Accept': 'application/json'
            }
          }
        );

        if (response.data && response.data.pairs && response.data.pairs.length > 0) {
          let pair = response.data.pairs.find((p) => 
            p.chainId === chainMap[chain]
          );
          
          if (!pair) {
            pair = response.data.pairs.reduce((best, current) => {
              const currentLiquidity = current.liquidity?.usd || 0;
              const bestLiquidity = best?.liquidity?.usd || 0;
              return currentLiquidity > bestLiquidity ? current : best;
            }, response.data.pairs[0]);
          }

          if (pair && pair.priceUsd) {
            const price = parseFloat(pair.priceUsd);
            console.log(`DexScreener成功获取价格: $${price}`);
            
            return {
              price,
              marketCap: pair.marketCap ? parseFloat(pair.marketCap) : null,
              volume24h: pair.volume?.h24 ? parseFloat(pair.volume.h24) : null,
              priceChange24h: pair.priceChange?.h24 ? parseFloat(pair.priceChange.h24) : null
            };
          }
        }

        if (attempt < this.maxRetries) {
          await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
        }
        
      } catch (error) {
        console.error(`DexScreener尝试 ${attempt} 失败:`, error.message);
        
        if (attempt < this.maxRetries) {
          await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
        }
      }
    }

    return null;
  }

  // 移除了随机RSI计算方法，现在使用真实价格历史
}

// 价格历史管理器（已废弃，现在使用数据库存储）
class PriceHistoryManager {
  constructor() {
    this.priceHistory = new Map(); // 保留兼容性，但不再使用
    this.maxHistoryLength = 60; // 保留兼容性
  }

  addPrice(tokenId, price) {
    if (!this.priceHistory.has(tokenId)) {
      this.priceHistory.set(tokenId, []);
    }
    
    const history = this.priceHistory.get(tokenId);
    history.push({
      price: price,
      timestamp: Date.now()
    });
    
    // 保持历史数据长度
    if (history.length > this.maxHistoryLength) {
      history.shift();
    }
  }

  getPriceHistory(tokenId) {
    return this.priceHistory.get(tokenId) || [];
  }

  calculateRSI(tokenId, period = 14) {
    const history = this.getPriceHistory(tokenId);
    const requiredPoints = period + 1; // RSI-14需要15个数据点
    
    if (history.length < requiredPoints) {
      const timeNeeded = (requiredPoints - history.length) * 2; // 每2秒一个点
      console.log(`代币 ${tokenId} RSI计算中... 当前: ${history.length}/${requiredPoints} 数据点，还需 ${timeNeeded}秒`);
      return null;
    }

    const prices = history.map(h => h.price);
    const gains = [];
    const losses = [];

    // 计算价格变化
    for (let i = 1; i < prices.length; i++) {
      const change = prices[i] - prices[i - 1];
      gains.push(change > 0 ? change : 0);
      losses.push(change < 0 ? Math.abs(change) : 0);
    }

    // 计算平均收益和损失
    const avgGain = gains.slice(-period).reduce((sum, gain) => sum + gain, 0) / period;
    const avgLoss = losses.slice(-period).reduce((sum, loss) => sum + loss, 0) / period;

    // 调试信息
    const recentPrices = prices.slice(-5); // 最近5个价格
    const recentGains = gains.slice(-period).filter(g => g > 0);
    const recentLosses = losses.slice(-period).filter(l => l > 0);
    
    console.log(`RSI调试 - 代币${tokenId}: 最近价格=[${recentPrices.map(p => p.toFixed(6)).join(', ')}]`);
    console.log(`收益次数=${recentGains.length}, 损失次数=${recentLosses.length}, 平均收益=${avgGain.toFixed(8)}, 平均损失=${avgLoss.toFixed(8)}`);

    // 处理价格无变化的情况
    if (avgGain === 0 && avgLoss === 0) {
      console.log(`RSI=50 因为价格无变化（中性值）`);
      return 50; // 价格无变化时返回中性值50
    }

    if (avgLoss === 0) {
      console.log(`RSI=100 因为只有收益无损失`);
      return 100;
    }

    const rs = avgGain / avgLoss;
    const rsi = 100 - (100 / (1 + rs));

    return Math.round(rsi * 100) / 100;
  }

  getHistoryLength(tokenId) {
    const history = this.getPriceHistory(tokenId);
    return history.length;
  }
}

// WebSocket价格监控类
class WebSocketPriceMonitor {
  constructor(io) {
    this.io = io;
    this.priceService = new PriceService();
    this.priceHistoryManager = new PriceHistoryManager();
    this.monitoringInterval = null;
    this.priceHistoryInterval = null;
    this.isMonitoring = false;
    this.lastPrices = new Map(); // 存储最新价格用于实时显示
  }

  startMonitoring() {
    if (this.isMonitoring) {
      console.log('价格监控已在运行中');
      return;
    }

    console.log('开始WebSocket价格监控...');
    this.isMonitoring = true;
    
    this.io.emit('monitoring-status', { isMonitoring: true });
    
    // 立即执行一次价格显示更新
    this.updatePricesForDisplay();
    
    // 每2秒更新价格显示
    this.monitoringInterval = setInterval(() => {
      this.updatePricesForDisplay();
    }, 2000);

    // 每60秒（1分钟）保存价格历史到数据库，符合1分钟RSI标准
    this.priceHistoryInterval = setInterval(() => {
      this.savePriceHistoryToDatabase();
    }, 60000);
  }

  stopMonitoring() {
    if (!this.isMonitoring) {
      console.log('价格监控未在运行');
      return;
    }

    console.log('停止WebSocket价格监控...');
    this.isMonitoring = false;
    
    if (this.monitoringInterval) {
      clearInterval(this.monitoringInterval);
      this.monitoringInterval = null;
    }

    if (this.priceHistoryInterval) {
      clearInterval(this.priceHistoryInterval);
      this.priceHistoryInterval = null;
    }
    
    this.io.emit('monitoring-status', { isMonitoring: false });
  }

  // 更新价格显示（不保存到数据库）
  async updatePricesForDisplay() {
    try {
      const tokens = await prisma.memeToken.findMany({
        where: { isActive: true }
      });

      if (tokens.length === 0) {
        console.log('没有找到活跃的代币');
        return;
      }

      console.log(`正在更新 ${tokens.length} 个代币的实时价格显示...`);

      const updatePromises = tokens.map(async (token) => {
        try {
          // 只获取价格数据用于显示
          const priceData = await this.priceService.getTokenPrice(token.contractAddress, token.chain.toLowerCase());

          if (priceData?.price) {
            // 存储最新价格到内存
            this.lastPrices.set(token.id, priceData.price);
          }

          // 实时计算RSI值（基于当前价格和历史数据）
          const latestRSI = await this.calculateRealTimeRSI(token.id, priceData?.price);

          const tokenData = {
            id: token.id,
            symbol: token.symbol,
            name: token.name,
            contractAddress: token.contractAddress,
            chain: token.chain,
            price: priceData?.price || null,
            marketCap: priceData?.marketCap || null,
            volume24h: priceData?.volume24h || null,
            priceChange24h: priceData?.priceChange24h || null,
            rsi: latestRSI,
            lastUpdated: new Date().toISOString()
          };

          return tokenData;
        } catch (error) {
          console.error(`获取代币 ${token.symbol} 显示数据失败:`, error);
          return {
            id: token.id,
            symbol: token.symbol,
            name: token.name,
            contractAddress: token.contractAddress,
            chain: token.chain,
            price: null,
            marketCap: null,
            volume24h: null,
            priceChange24h: null,
            rsi: null,
            lastUpdated: new Date().toISOString(),
            error: '数据获取失败'
          };
        }
      });

      const results = await Promise.all(updatePromises);
      
      // 广播更新的数据到所有连接的客户端
      this.io.emit('price-update', {
        tokens: results,
        timestamp: new Date().toISOString()
      });

      const successCount = results.filter(r => r.price !== null).length;
      console.log(`实时价格显示更新完成: ${successCount}/${results.length} 成功`);

    } catch (error) {
      console.error('更新实时价格显示时出错:', error);
      
      this.io.emit('price-update-error', {
        error: '价格显示更新失败',
        timestamp: new Date().toISOString()
      });
    }
  }

  // 保存价格历史到数据库（用于RSI计算）
  async savePriceHistoryToDatabase() {
    try {
      const tokens = await prisma.memeToken.findMany({
        where: { isActive: true }
      });

      console.log(`正在保存 ${tokens.length} 个代币的1分钟价格历史到数据库...`);

      const savePromises = tokens.map(async (token) => {
        try {
          const priceData = await this.priceService.getTokenPrice(token.contractAddress, token.chain.toLowerCase());

          if (priceData?.price) {
            // 保存到数据库
            await prisma.priceData.create({
              data: {
                tokenId: token.id,
                price: priceData.price,
                marketCap: priceData.marketCap || 0,
                volume24h: priceData.volume24h || 0,
                rsi: null, // RSI将在下次计算时更新
                timestamp: new Date()
              }
            });


            console.log(`保存1分钟价格历史: ${token.symbol} = $${priceData.price}`);
            return true;
          }
          return false;
        } catch (error) {
          console.error(`保存代币 ${token.symbol} 价格历史失败:`, error);
          return false;
        }
      });

      const results = await Promise.all(savePromises);
      const successCount = results.filter(r => r).length;
      console.log(`1分钟价格历史保存完成: ${successCount}/${tokens.length} 成功`);

    } catch (error) {
      console.error('保存价格历史到数据库时出错:', error);
    }
  }

  // 实时计算RSI值（基于当前价格和历史数据）
  async calculateRealTimeRSI(tokenId, currentPrice, period = 14) {
    try {
      if (!currentPrice) {
        // 如果没有当前价格，回退到数据库RSI
        return await this.calculateRSIFromDatabase(tokenId, period);
      }

      // 获取最近30条1分钟价格记录
      const priceRecords = await prisma.priceData.findMany({
        where: { tokenId },
        orderBy: { timestamp: 'desc' },
        take: 30
      });

      if (priceRecords.length < period) {
        console.log(`代币 ${tokenId} 实时RSI计算: 历史数据不足，当前: ${priceRecords.length}, 需要: ${period}`);
        return null;
      }

      // 按时间正序排列，并添加当前价格
      const historicalPrices = priceRecords.reverse().map(record => record.price);
      const allPrices = [...historicalPrices, currentPrice];
      
      // 标准RSI计算（使用Wilder's平滑方法）
      const changes = [];
      
      // 计算价格变化（包括到当前价格的变化）
      for (let i = 1; i < allPrices.length; i++) {
        changes.push(allPrices[i] - allPrices[i - 1]);
      }

      if (changes.length < period) {
        console.log(`代币 ${tokenId} 实时RSI计算: 变化数据不足，当前: ${changes.length}, 需要: ${period}`);
        return null;
      }

      // 计算初始的平均收益和损失（前14个周期使用SMA）
      let avgGain = 0;
      let avgLoss = 0;
      
      const startIndex = Math.max(0, changes.length - period * 2); // 使用更多历史数据以获得更准确的初始值
      const initialPeriodEnd = Math.min(startIndex + period, changes.length);
      
      for (let i = startIndex; i < initialPeriodEnd; i++) {
        if (changes[i] > 0) {
          avgGain += changes[i];
        } else {
          avgLoss += Math.abs(changes[i]);
        }
      }
      
      avgGain /= period;
      avgLoss /= period;

      // 使用Wilder's平滑方法计算后续的平均值
      for (let i = initialPeriodEnd; i < changes.length; i++) {
        const gain = changes[i] > 0 ? changes[i] : 0;
        const loss = changes[i] < 0 ? Math.abs(changes[i]) : 0;
        
        // Wilder's平滑公式：新平均 = (旧平均 * (期间-1) + 新值) / 期间
        avgGain = (avgGain * (period - 1) + gain) / period;
        avgLoss = (avgLoss * (period - 1) + loss) / period;
      }

      // 处理边界情况
      if (avgGain === 0 && avgLoss === 0) {
        return 50; // 价格无变化时返回中性值50
      }

      if (avgLoss === 0) {
        return 100;
      }

      const rs = avgGain / avgLoss;
      const rsi = 100 - (100 / (1 + rs));

      console.log(`代币 ${tokenId} 实时RSI计算详情: 平均收益=${avgGain.toFixed(6)}, 平均损失=${avgLoss.toFixed(6)}, RS=${rs.toFixed(4)}, RSI=${rsi.toFixed(2)}`);

      console.log(`实时RSI计算: 代币${tokenId}, 当前价格=$${currentPrice}, RSI=${rsi.toFixed(2)}, 数据点=${allPrices.length}`);
      return Math.round(rsi * 100) / 100;

    } catch (error) {
      console.error(`实时RSI计算失败 ${tokenId}:`, error);
      // 出错时回退到数据库RSI
      return await this.calculateRSIFromDatabase(tokenId, period);
    }
  }

  // 从数据库计算1分钟RSI（保留作为备用方法）
  async calculateRSIFromDatabase(tokenId, period = 14) {
    try {
      // 获取最近30条1分钟价格记录（足够计算RSI-14）
      const priceRecords = await prisma.priceData.findMany({
        where: { tokenId },
        orderBy: { timestamp: 'desc' },
        take: 30
      });

      if (priceRecords.length < period + 1) {
        console.log(`代币 ${tokenId} 1分钟价格历史不足，当前: ${priceRecords.length}, 需要: ${period + 1} (约${period + 1}分钟数据)`);
        return null;
      }

      // 按时间正序排列
      const prices = priceRecords.reverse().map(record => record.price);
      
      const gains = [];
      const losses = [];

      // 计算价格变化
      for (let i = 1; i < prices.length; i++) {
        const change = prices[i] - prices[i - 1];
        gains.push(change > 0 ? change : 0);
        losses.push(change < 0 ? Math.abs(change) : 0);
      }

      // 计算平均收益和损失
      const avgGain = gains.slice(-period).reduce((sum, gain) => sum + gain, 0) / period;
      const avgLoss = losses.slice(-period).reduce((sum, loss) => sum + loss, 0) / period;

      // 处理价格无变化的情况
      if (avgGain === 0 && avgLoss === 0) {
        return 50; // 价格无变化时返回中性值50
      }

      if (avgLoss === 0) {
        return 100;
      }

      const rs = avgGain / avgLoss;
      const rsi = 100 - (100 / (1 + rs));

      console.log(`1分钟RSI计算: 代币${tokenId}, RSI=${rsi.toFixed(2)}, 数据点=${prices.length}分钟`);
      return Math.round(rsi * 100) / 100;

    } catch (error) {
      console.error(`从数据库计算RSI失败 ${tokenId}:`, error);
      return null;
    }
  }

  // 保留原方法名以兼容现有代码
  async updatePricesAndRSI() {
    try {
      const tokens = await prisma.memeToken.findMany({
        where: { isActive: true }
      });

      if (tokens.length === 0) {
        console.log('没有找到活跃的代币');
        return;
      }

      console.log(`正在更新 ${tokens.length} 个代币的价格和RSI数据...`);

      const updatePromises = tokens.map(async (token) => {
        try {
          // 只获取价格数据，不再使用随机RSI
          const priceData = await this.priceService.getTokenPrice(token.contractAddress, token.chain.toLowerCase());

          let rsiValue = null;
          
          if (priceData?.price) {
            // 将新价格添加到历史记录
            this.priceHistoryManager.addPrice(token.id, priceData.price);
            
            // 使用真实价格历史计算RSI
            rsiValue = this.priceHistoryManager.calculateRSI(token.id);
            
            console.log(`代币 ${token.symbol}: 价格=$${priceData.price}, RSI=${rsiValue}, 历史数据点=${this.priceHistoryManager.getHistoryLength(token.id)}`);
          }

          const tokenData = {
            id: token.id,
            symbol: token.symbol,
            name: token.name,
            contractAddress: token.contractAddress,
            chain: token.chain,
            price: priceData?.price || null,
            marketCap: priceData?.marketCap || null,
            volume24h: priceData?.volume24h || null,
            priceChange24h: priceData?.priceChange24h || null,
            rsi: rsiValue,
            lastUpdated: new Date().toISOString()
          };

          // 保存到数据库（包括真实的RSI）
          if (priceData?.price) {
            await prisma.priceData.create({
              data: {
                tokenId: token.id,
                price: priceData.price,
                marketCap: priceData.marketCap || 0,
                rsi: rsiValue || 50, // 如果RSI为null，使用中性值50
                timestamp: new Date()
              }
            });
          }

          return tokenData;
        } catch (error) {
          console.error(`获取代币 ${token.symbol} 数据失败:`, error);
          return {
            id: token.id,
            symbol: token.symbol,
            name: token.name,
            contractAddress: token.contractAddress,
            chain: token.chain,
            price: null,
            marketCap: null,
            volume24h: null,
            priceChange24h: null,
            rsi: null,
            lastUpdated: new Date().toISOString(),
            error: '数据获取失败'
          };
        }
      });

      const results = await Promise.all(updatePromises);
      
      this.io.emit('price-update', {
        tokens: results,
        timestamp: new Date().toISOString()
      });

      const successCount = results.filter(r => r.price !== null).length;
      const failCount = results.length - successCount;
      
      console.log(`价格更新完成: ${successCount} 成功, ${failCount} 失败`);

    } catch (error) {
      console.error('更新价格和RSI数据时出错:', error);
      
      this.io.emit('price-update-error', {
        error: '价格更新失败',
        timestamp: new Date().toISOString()
      });
    }
  }


  close() {
    this.stopMonitoring();
  }
}

async function startServer() {
  try {
    await app.prepare();
    
    const server = createServer(async (req, res) => {
      try {
        const parsedUrl = parse(req.url, true);
        await handle(req, res, parsedUrl);
      } catch (err) {
        console.error('处理请求时出错:', err);
        res.statusCode = 500;
        res.end('内部服务器错误');
      }
    });

    // 创建Socket.IO服务器
    const io = new Server(server, {
      cors: {
        origin: dev ? ['http://localhost:3000'] : false,
        methods: ['GET', 'POST']
      }
    });

    // 创建WebSocket价格监控服务
    const priceMonitor = new WebSocketPriceMonitor(io);
    
    // 设置Socket.IO事件处理
    io.on('connection', (socket) => {
      console.log('客户端已连接:', socket.id);
      
      socket.emit('monitoring-status', { isMonitoring: priceMonitor.isMonitoring });
      
      socket.on('start-monitoring', () => {
        priceMonitor.startMonitoring();
      });
      
      socket.on('stop-monitoring', () => {
        priceMonitor.stopMonitoring();
      });
      
      socket.on('disconnect', () => {
        console.log('客户端已断开连接:', socket.id);
      });
    });

    server.listen(port, () => {
      console.log(`> 服务器已启动: http://${hostname}:${port}`);
      console.log('> WebSocket价格监控服务已就绪');
    });

    // 优雅关闭处理
    process.on('SIGTERM', () => {
      console.log('收到SIGTERM信号，正在关闭服务器...');
      priceMonitor.close();
      server.close(() => {
        console.log('服务器已关闭');
        process.exit(0);
      });
    });

    process.on('SIGINT', () => {
      console.log('收到SIGINT信号，正在关闭服务器...');
      priceMonitor.close();
      server.close(() => {
        console.log('服务器已关闭');
        process.exit(0);
      });
    });

  } catch (error) {
    console.error('启动服务器失败:', error);
    process.exit(1);
  }
}

startServer();
